package Lab3;
import static org.junit.Assert.assertTrue;
import org.junit.Before;
import org.junit.Test;

public class LinkedListTest {
	
	Worker a;
	Worker b;
	Worker c;
	Worker d;
	Worker e;
	
	Worker x;
	Worker y;
	Worker z;
	
	LinkedList<Worker> aList;
	LinkedList<Worker> secondList;

	@Before
	public void setUp() throws Exception {
		
		a = new Worker("a", "Maintenance");
		b = new Worker("b", "Electrician");
		c = new Worker("c", "Electrician");
		d = new Worker("d", "Electrician");
		e = new Worker("e", "Electrician");
		
		x = new Worker("x", "Electrician");
		y = new Worker("y", "Electrician");
		z = new Worker("z", "Electrician");
		
		aList = new LinkedList<Worker>();
		
		aList.add(a);
		aList.add(b);
		aList.add(c);
	}
	
	@Test
	public void replaceFirst() {
		aList.replace(0, x);
		
		assertTrue(aList.size() == 3);
		
		assertTrue(aList.getPosition(0) == x);
		assertTrue(aList.getPosition(1) == b);
		assertTrue(aList.getPosition(2) == c);
	}
	
	@Test
	public void replaceMiddle() {
		aList.replace(1, x);
		
		assertTrue(aList.size() == 3);
		
		assertTrue(aList.getPosition(0) == a);
		assertTrue(aList.getPosition(1) == x);
		assertTrue(aList.getPosition(2) == c);
	}
	
	@Test
	public void replaceLast() {
		aList.replace(2, x);
		
		assertTrue(aList.size() == 3);
		
		assertTrue(aList.getPosition(0) == a);
		assertTrue(aList.getPosition(1) == b);
		assertTrue(aList.getPosition(2) == x);		
	}
	
	@Test
	public void addAllBothListsHaveItems() {
		secondList = new LinkedList<Worker>();
		
		secondList.add(x);
		secondList.add(y);
		secondList.add(z);
		
		aList.addAll(secondList);
		
		assertTrue(aList.size() == 6);
		
		assertTrue(aList.getPosition(0) == a);
		assertTrue(aList.getPosition(1) == b);
		assertTrue(aList.getPosition(2) == c);
		
		assertTrue(aList.getPosition(3) == x);
		assertTrue(aList.getPosition(4) == y);
		assertTrue(aList.getPosition(5) == z);
		
		assertTrue(secondList.size() == 3);
		
		assertTrue(secondList.getPosition(0) == x);
		assertTrue(secondList.getPosition(1) == y);
		assertTrue(secondList.getPosition(2) == z);
	}
	
	@Test
	public void addAllBothListsHaveOne() {	
		LinkedList<Worker> aList = new LinkedList<>();
		aList.add(a);
	
		secondList = new LinkedList<Worker>();
		
		secondList.add(x);

		
		aList.addAll(secondList);
		
		assertTrue(aList.size() == 2);
		
		assertTrue(aList.getPosition(0) == a);
		assertTrue(aList.getPosition(1) == x);
		
		assertTrue(secondList.size() == 1);
		
		assertTrue(secondList.getPosition(0) == x);
	}
	
	@Test
	public void addAllIntoEmpty() {
		LinkedList<Worker> aList = new LinkedList<>();
		
		LinkedList<Worker> secondList = new LinkedList<Worker>();
		
		secondList.add(x);
		secondList.add(y);
		secondList.add(z);
		
		aList.addAll(secondList);
		
		assertTrue(aList.size() == 3);
		
		assertTrue(aList.getPosition(0) == x);
		assertTrue(aList.getPosition(1) == y);
		assertTrue(aList.getPosition(2) == z);
		
		assertTrue(secondList.size() == 3);
		
		assertTrue(secondList.getPosition(0) == x);
		assertTrue(secondList.getPosition(1) == y);
		assertTrue(secondList.getPosition(2) == z);
	}
	
	@Test
	public void addAllFromEmpty() {
		LinkedList<Worker> secondList = new LinkedList<Worker>();
		
		aList.addAll(secondList);

		assertTrue(aList.size() == 3);
		
		assertTrue(aList.getPosition(0) == a);
		assertTrue(aList.getPosition(1) == b);
		assertTrue(aList.getPosition(2) == c);
		
		assertTrue(secondList.size() == 0);
	}
	
	@Test
	public void addAllIndependentLists() {
		addAllBothListsHaveItems();
		
		secondList.remove(1);
		
		assertTrue(aList.size() == 6);
		
		assertTrue(aList.getPosition(0) == a);
		assertTrue(aList.getPosition(1) == b);
		assertTrue(aList.getPosition(2) == c);
		
		assertTrue(aList.getPosition(3) == x);
		assertTrue(aList.getPosition(4) == y);
		assertTrue(aList.getPosition(5) == z);
		
		assertTrue(secondList.size() == 2);
		
		assertTrue(secondList.getPosition(0) == x);
		assertTrue(secondList.getPosition(1) == z);
	}
	
	@Test
	public void initialSizeEmpty() {
		aList = new LinkedList<>();
		assertTrue(aList.size() == 0);
	}
	
	@Test
	public void addOneThenRetrieve() {
		aList = new LinkedList<>();
		aList.add(a);
		
		Worker who = (Worker) aList.getPosition(0);
		assertTrue(who == a);
		assertTrue(aList.size() == 1);
	}
	
	@Test
	public void addMany() {
		aList = new LinkedList<>();
		aList.add(a);
		aList.add(b);
		
		assertTrue(aList.size() == 2);
		assertTrue(aList.getPosition(0) == a);
		assertTrue(aList.getPosition(1) == b);
	}
	
	@Test
	public void removeBeginning() {
		aList = new LinkedList<>();
		aList.add(a);
		aList.add(b);
		aList.add(c);
		aList.add(d);
		aList.add(e);
		assertTrue(aList.size() == 5);
		
		aList.remove(0);
		
		assertTrue(aList.getPosition(0) == b);
		assertTrue(aList.getPosition(1) == c);
		assertTrue(aList.getPosition(2) == d);
		assertTrue(aList.getPosition(3) == e);
	}
	
	@Test
	public void removeMiddle() {
		aList = new LinkedList<>();
		aList.add(a);
		aList.add(b);
		aList.add(c);
		aList.add(d);
		aList.add(e);
		assertTrue(aList.size() == 5);
		
		aList.remove(2);
		
		assertTrue(aList.getPosition(0) == a);
		assertTrue(aList.getPosition(1) == b);
		assertTrue(aList.getPosition(2) == d);
		assertTrue(aList.getPosition(3) == e);		
	}

	@Test
	public void removeEnd() {
		aList = new LinkedList<>();
		aList.add(a);
		aList.add(b);
		aList.add(c);
		aList.add(d);
		aList.add(e);
		assertTrue(aList.size() == 5);
		
		aList.remove(4);
		
		assertTrue(aList.getPosition(0) == a);
		assertTrue(aList.getPosition(1) == b);
		assertTrue(aList.getPosition(2) == c);
		assertTrue(aList.getPosition(3) == d);		
		
	}
}
